using System.Diagnostics;
using System.Globalization;
using CsvHelper;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using NetTopologySuite.IO;
using Newtonsoft.Json;
using SkiaSharp;

namespace KrigingTest;

public class Test2
{
    public static async Task Start()
    {
        var jsonStr = PointHelper.LoadGeoJson("tmp.json");

        var jsonData = jsonStr["data"];
        var coordinate = jsonData["Coordinate"];
        var boundary = coordinate["Boundary"];
        double minLon = (double)boundary["MinLongitude"];
        double maxLon = (double)boundary["MaxLongitude"];
        double minLat = (double)boundary["MinLatitude"];
        double maxLat = (double)boundary["MaxLatitude"];
        var listData = JsonConvert.DeserializeObject<List<List<double>>>(jsonData["Values"].ToString());

        int rows = listData.Count;
        int cols = listData[0].Count;

        var sw = new Stopwatch();
        sw.Start();

        int height = 1000;

        // 将最小和最大经纬度转换为 EPSG:3857
        var minCoords = PointHelper.ConvertToEPSG3857(minLon, minLat);
        var maxCoords = PointHelper.ConvertToEPSG3857(maxLon, maxLat);
        //
        double lonRange = maxCoords.x - minCoords.x;
        double latRange = maxCoords.y - minCoords.y;
        // double lonRange = maxLon - minLon;
        // double latRange = maxLat - minLat;

        // 计算宽度，根据纬度范围与高度的比例
        int width = (int)(lonRange / latRange * height);

        Console.WriteLine($"高度和宽度是: {height}, {width}");

        Console.WriteLine($"最小和最大经度纬度是: {minLon}, {maxLon}, {minLat}, {maxLat}");
        Console.WriteLine($"EPSG:3857最小和最大经度纬度是: {minCoords.x}, {maxCoords.x}, {minCoords.y}, {maxCoords.y}");

        var polygon = PointHelper.BuildPolygon("安徽省.json", true);

        // 创建图像
        var imageInfo = new SKImageInfo(width, height);
        using var surface = SKSurface.Create(imageInfo);
        var canvas = surface.Canvas;

        // 设定插值参数
        double maxDistance = 10000; // 根据实际情况调整
        double delta = 1000; // 网格间隔

        var colors = GetTmpColors().Values.ToArray();
        var levels = GetTmpColors().Keys.ToArray();

        // 不要频繁初始化
        using var paint = new SKPaint();
        paint.Style = SKPaintStyle.Fill;
        paint.IsAntialias = false; // 开启抗锯齿
        
        bool[,] maskGrid = PointHelper.CreateMaskGrid(minCoords.x, maxCoords.x, minCoords.y, maxCoords.y, rows, cols, polygon);
        
        int count = 0;

        // 绘制色斑图
        // for (int i = 0; i < rows; i++)
        // {
        //     for (int j = 0; j < cols; j++)
        //     {
        //         if (!maskGrid[i, j]) continue;
        //
        //         var value = listData[i][j];
        //
        //         if (value >= 9999) count += 1;
        //
        //         var color = GetColorForValue(value, colors, levels);
        //
        //         paint.Color = color;
        //
        //         float left = (float)(j * ((double)width / cols));
        //         float top = (float)((rows - i - 1) * ((double)height / rows)); // 调整 y 坐标
        //         float right = (float)((j + 1) * ((double)width / cols));
        //         float bottom = (float)((rows - i) * ((double)height / rows)); // 调整 y 坐标
        //
        //         canvas.DrawRect(new SKRect(left, top, right, bottom), paint);
        //     }
        // }

        Console.WriteLine($"9999的值有: {count}");

        // 保存图像
        using var image = surface.Snapshot();
        using var data = image.Encode();
        using var stream = File.OpenWrite("heatmap.png");

        data.SaveTo(stream);
        sw.Stop();

        Console.WriteLine($"处理完成，用时: {sw.Elapsed.TotalSeconds}");
    }


    static List<Coordinate[]> ReadGeoJson(string filePath)
    {
        var geoJsonReader = new GeoJsonReader();
        using var stream = new StreamReader(filePath);
        var featureCollection = geoJsonReader.Read<FeatureCollection>(stream.ReadToEnd());
        var boundaryCoordinates = new List<Coordinate[]>();

        foreach (var feature in featureCollection)
        {
            var geometry = feature.Geometry;
            if (geometry is Polygon polygon)
            {
                boundaryCoordinates.Add(polygon.ExteriorRing.Coordinates);
            }
        }

        return boundaryCoordinates;
    }

    static SKColor GetColorForValue(double value, SKColor[] colors, int[] levels)
    {
        for (int i = 0; i < levels.Length - 1; i++)
        {
            if (value >= levels[i] && value < levels[i + 1])
            {
                return colors[i];
            }
        }

        return new SKColor(0, 0, 0, 0); // 超出范围，返回最后一种颜色
    }

    static List<DataRecord> ReadCsv(string filePath)
    {
        using var reader = new StreamReader(filePath);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        return new List<DataRecord>(csv.GetRecords<DataRecord>());
    }

// 边界绘制函数
// DrawBoundary 函数
    static void DrawBoundary(SKCanvas canvas, List<Coordinate[]> boundaryCoordinates, double minLon, double maxLon,
        double minLat, double maxLat, int width, int height)
    {
        var paint = new SKPaint
        {
            Color = new SKColor(0, 0, 0), // 边界线的颜色
            IsStroke = true,
            StrokeWidth = 2
        };

        foreach (var polygon in boundaryCoordinates)
        {
            using (var path = new SKPath())
            {
                for (int i = 0; i < polygon.Length; i++)
                {
                    // 将经纬度坐标转换为画布上的像素坐标
                    float x = (float)((polygon[i].X - minLon) / (maxLon - minLon) * width);
                    float y = (float)((1 - (polygon[i].Y - minLat) / (maxLat - minLat)) * height); // 反转 Y 轴以匹配画布坐标系

                    if (i == 0)
                    {
                        path.MoveTo(x, y); // 移动到第一个点
                    }
                    else
                    {
                        path.LineTo(x, y); // 连线到后续的点
                    }
                }

                path.Close(); // 封闭路径
                canvas.DrawPath(path, paint); // 绘制路径
            }
        }
    }

    private static Dictionary<int, SKColor> GetTmpColors()
    {
        return new Dictionary<int, SKColor>
        {
            { -22, new SKColor(155, 97, 184) }, // #9B61B8
            { -21, new SKColor(139, 89, 176) }, // #8B59B0
            { -20, new SKColor(123, 81, 169) }, // #7B51A9
            { -19, new SKColor(123, 81, 169) }, // #7B51A9
            { -18, new SKColor(138, 106, 183) }, // #8A6AB7
            { -17, new SKColor(153, 132, 197) }, // #9984C5
            { -16, new SKColor(168, 158, 211) }, // #A89ED3
            { -15, new SKColor(183, 184, 226) }, // #B7B8E2
            { -14, new SKColor(183, 184, 226) }, // #B7B8E2
            { -13, new SKColor(156, 156, 215) }, // #9C9CD7
            { -12, new SKColor(129, 128, 204) }, // #8180CC
            { -11, new SKColor(102, 100, 193) }, // #6664C1
            { -10, new SKColor(76, 73, 182) }, // #4C49B6
            { -9, new SKColor(76, 73, 182) }, // #4C49B6
            { -8, new SKColor(68, 90, 200) }, // #445AC8
            { -7, new SKColor(60, 108, 218) }, // #3C6CDA
            { -6, new SKColor(52, 126, 236) }, // #347EEC
            { -5, new SKColor(44, 144, 254) }, // #2C90FE
            { -4, new SKColor(44, 144, 254) }, // #2C90FE
            { -3, new SKColor(34, 171, 254) }, // #22ABFE
            { -2, new SKColor(24, 199, 254) }, // #18C7FE
            { -1, new SKColor(14, 227, 254) }, // #0EE3FE
            { 0, new SKColor(4, 255, 255) }, // #04FFFF
            { 1, new SKColor(109, 231, 153) }, // #6DE799
            { 2, new SKColor(94, 220, 132) }, // #5EDC84
            { 3, new SKColor(79, 209, 112) }, // #4FD170
            { 4, new SKColor(65, 199, 92) }, // #41C75C
            { 5, new SKColor(50, 188, 71) }, // #32BC47
            { 6, new SKColor(35, 177, 51) }, // #23B133
            { 7, new SKColor(21, 167, 31) }, // #15A71F
            { 8, new SKColor(21, 167, 31) }, // #15A71F
            { 9, new SKColor(54, 176, 43) }, // #36B02B
            { 10, new SKColor(87, 186, 55) }, // #57BA37
            { 11, new SKColor(120, 196, 68) }, // #78C444
            { 12, new SKColor(153, 205, 80) }, // #99CD50
            { 13, new SKColor(186, 215, 93) }, // #BAD75D
            { 14, new SKColor(219, 225, 105) }, // #DBE169
            { 15, new SKColor(253, 235, 118) }, // #FDEB76
            { 16, new SKColor(253, 235, 118) }, // #FDEB76
            { 17, new SKColor(246, 212, 106) }, // #F6D46A
            { 18, new SKColor(239, 189, 95) }, // #EFBD5F
            { 19, new SKColor(232, 167, 84) }, // #E8A754
            { 20, new SKColor(226, 144, 73) }, // #E19049
            { 21, new SKColor(218, 121, 61) }, // #DA793D
            { 22, new SKColor(211, 99, 50) }, // #D36332
            { 23, new SKColor(204, 76, 39) }, // #CC4C27
            { 24, new SKColor(197, 53, 28) }, // #C5351C
            { 25, new SKColor(191, 31, 17) }, // #BF1F11
            { 26, new SKColor(191, 31, 17) }, // #BF1F11
            { 27, new SKColor(183, 31, 25) }, // #B71F19
            { 28, new SKColor(175, 31, 34) }, // #AF1F22
            { 29, new SKColor(167, 31, 42) }, // #A71F2A
            { 30, new SKColor(159, 32, 51) }, // #9F2033
            { 31, new SKColor(159, 32, 51) }, // #9F2033
            { 32, new SKColor(168, 48, 72) }, // #A83048
            { 33, new SKColor(178, 65, 93) }, // #B2415D
            { 34, new SKColor(188, 82, 115) }, // #BC5273
            { 35, new SKColor(197, 99, 136) }, // #C56388
            { 36, new SKColor(207, 116, 158) }, // #CF739E
            { 37, new SKColor(217, 132, 179) }, // #D984B3
            { 38, new SKColor(226, 149, 201) }, // #E295C9
            { 39, new SKColor(236, 166, 222) }, // #ECA6DE
            { 40, new SKColor(246, 183, 244) }, // #F6B7F4
            { 41, new SKColor(246, 183, 244) }, // #F6B7F4
            { 42, new SKColor(214, 165, 232) }, // #D6A5E8
            { 43, new SKColor(182, 148, 221) }, // #B694DD
            { 44, new SKColor(150, 131, 210) } // #9683D2
        };
    }
}